﻿using IndexedList;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.DataVisualization.Charting;

namespace Demo
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }


        List<Person> personList = new List<Person>();
        IIndexedList<Person> personIndexedList = new IndexedList<Person>();

        private void Form1_Load(object sender, EventArgs e)
        {
            personIndexedList.AddUniqueIndex(p => p.Id);
            personIndexedList.AddIndex(p => new { p.Name, p.Family });
        }

        private void Btn_Start_Click(object sender, EventArgs e)
        {
            Btn_Start.Text = "Wait ...";
            Application.DoEvents();

            chart1.Series.Clear();

            List<Series> serieslist = new List<Series>{
                new Series("List"){ChartType = SeriesChartType.Spline},
                new Series("IndexedList(Expression)"){ChartType = SeriesChartType.Spline},
                new Series("IndexedList(No Expression)"){ChartType = SeriesChartType.Spline }
            };

            serieslist.ForEach(s =>
            {
                chart1.Series.Add(s);
            });

            List<int> datas = new List<int> { 1000, 5000, 10000, 15000 };

            datas.ForEach(d =>
            {
                ShowResult(DoTest(d), d);
            });

            Btn_Start.Text = "Start";
        }

        void ShowResult(List<long> result, double Xvalue)
        {
            for (int i = 0; i < 3; i++)
            {
                chart1.Series[i].Points.Add(new DataPoint(Xvalue, result[i]));
            }
        }

        List<long> DoTest(int datacount)
        {
            FillMockData(datacount);
            List<long> result = new List<long>();

            Stopwatch sw = new Stopwatch();

            sw.Restart();
            for (int i = 0; i < datacount; i++)
            {
                string pname = personList[i].Name;
                string pfamily = personList[i].Family;

                personList.Where(p => p.Id == i).FirstOrDefault();
                personList.Where(p => p.Name == pname && p.Family == pfamily).FirstOrDefault();
            }
            result.Add(sw.ElapsedMilliseconds);

            sw.Restart();
            for (int i = 0; i < datacount; i++)
            {
                string pname = personList[i].Name;
                string pfamily = personList[i].Family;

                personIndexedList.Find(p => p.Id == i);
                personIndexedList.Find(p => p.Name == pname && p.Family == pfamily);
            }
            result.Add(sw.ElapsedMilliseconds);

            sw.Restart();
            for (int i = 0; i < datacount; i++)
            {
                string pname = personList[i].Name;
                string pfamily = personList[i].Family;

                personIndexedList.Find((long)i);
                personIndexedList.Find(pname, pfamily);
            }
            result.Add(sw.ElapsedMilliseconds);

            sw.Stop();

            return result;

        }

        void FillMockData(int datacount)
        {
            personIndexedList.Clear();
            personList.Clear();

            for (int i = 0; i < datacount; i++)
            {
                Person p = new Person()
                {
                    Id = i,
                    Name = GenerateRandomString(),
                    Family = GenerateRandomString(),
                    NationalNo = GenerateRandomString(),
                    BirthDate = DateTime.Now.AddDays(-rnd.Next(1, 10000))
                };

                personIndexedList.Add(p);
                personList.Add(p);
            }
        }

        Random rnd = new Random();
        string GenerateRandomString()
        {
            int stringlen = rnd.Next(3, 15);
            string str = "";

            for (int i = 0; i < stringlen; i++)
            {//122
                str += (char)rnd.Next(97, 100);
            }
            return str;
        }


    }
}
